package EA.testproblems;
import EA.*;

/**
This testproblem is a simple problem for initial tuning of multimodal 
optimization algorithms. <br><br>

<table border="0" cellpadding="2" cellspacing="0">
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem description</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top" width="200"><b>Name:</b></td>
  <td valign="top">Ursem multimodal 6</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Nickname:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Intended usage:</b></td>
  <td valign="top">Test of a multimodal algoritms is capable of spotting 
very shallow peaks much smaller than global maxima and far from it.
</td>
</tr>

<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem details</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Function:</b></td>
  <td valign="top">(25+(10*sin((x*cos(x)+y)/(2*pi))*cos((x)/30*pi)))/(4+sqrt((x-4.5)<sup>2</sup>+(y+2)<sup>2</sup>))
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Plots:</b></td>
  <td valign="top"><img src="../../images/testproblems/ursemmultimodal6.gif">&nbsp;&nbsp;
<img src="../../images/testproblems/ursemmultimodal6_contour.gif"></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Ranges:</b></td>
  <td valign="top">x = [-15:15]&nbsp;&nbsp;y = [-15:55] </td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Type:</b></td>
  <td valign="top">Maximization</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of maximas:</b></td>
  <td valign="top">?</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of minimas:</b></td>
  <td valign="top">?</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum radius:</b></td>
  <td valign="top">0.2
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum descriptions:</b></td>
  <td valign="top">The global maxima and most of the local maximas are 
  located at one end of the search space. Some of these maximas are
  hard to detect.
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Known optimums:</b></td>
  <td valign="top">
  GMAX(5.535415047, -1.761005495),
  LMAX(-3.248986896, 43.25186785), 
  LMAX(-2.705230959, 1.800707895), 
  LMAX(.8350268284, 46.13254350), 
  LMAX(-8.692776867, .9110320673), 
  LMAX(-9.385345053, 35.05893623), 
  LMAX(6.312495470, 39.35543889), 
  LMAX(-14.32210170, -.2074153009), 
  LMAX(11.63283611, -1.052292700), 
  LMAX(-12.40494188, -8.635704653), 
  LMAX(1.761618060, -.5600474989), 
  LMAX(-.7219740352, -15),
  LMAX(3.459781511, -15),
  LMAX(-6.313520218, -15)<br>
  LMIN(-.8294517606, 31.76023712), 
  LMIN(9.344061604, 41.96316669), 
  LMIN(-6.224943897, 37.69999076), 
  LMIN(3.179425105, 34.44283535), 
  LMIN(.6694167291, -14.45528166),
  LMIN(-15, -15), 
  LMIN(-10.45037595, -15), 
  LMIN(-8.476812089, -15), 
  LMIN(-3.473009471, -15), 
  LMIN(.6972380782,-15),
  LMIN(5.651554158, -15), 
  LMIN(11.41930288, -15),
  LMIN(13.68624880, -15), 
  LMIN(15, -15),
  LMIN(-14.72118907, 55),
  LMIN(-12.78820084, 55), 
  LMIN(-9.429541428, 55), 
  LMIN(-3.445577891, 55),
  LMIN(.8677792011, 55), 
  LMIN(6.410963111, 55),
  LMIN(9.702169436, 55),
  LMIN(12.23452901, 55),
  LMIN(15, 55), 
  <br><font size=1>Capital letters 
means that the precise optimum is known, lowercase letters is the best known 
so far.</font></td>
</tr>
<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Plotting details</b></td>
</tr>

<tr bgcolor="#e0e0e0">
  <td valign="top"><b>GNUPlot code:</b></td>
  <td valign="top">
  set hidden3d<br>
  set isosamples 70<br>
  set view 70,230<br>
splot [-15:15] [-15:55] (25+(10*sin((x*cos(x)+y)/(2*pi))*cos((x)/30*pi)))/(4+sqrt((x-4.5)**2+(y+2)**2))
</td>

</tr>

</table>

*/
public class UrsemMultimodal6 extends NumericalProblem
{

  // Easier way to build max
  private double[][] lmax = {{-3.248986896, 43.25186785}, 
			     {-2.705230959, 1.800707895}, 
			     {.8350268284, 46.13254350}, 
			     {-8.692776867, .9110320673}, 
			     {-9.385345053, 35.05893623}, 
			     {6.312495470, 39.35543889}, 
			     {-14.32210170, -.2074153009}, 
			     {11.63283611, -1.052292700}, 
			     {-12.40494188, -8.635704653}, 
			     {1.761618060, -.5600474989}, 
			     {5.535415047, -1.761005495},
			     {-.7219740352, -15},
			     {3.459781511, -15},
			     {-6.313520218, -15}};

  private double[][] lmin =  {{-.8294517606, 31.76023712}, 
			      {9.344061604, 41.96316669}, 
			      {-6.224943897, 37.69999076}, 
			      {3.179425105, 34.44283535}, 
			      {.6694167291, -14.45528166},
			      {-15, -15}, 
			      {-10.45037595, -15}, 
			      {-8.476812089, -15}, 
			      {-3.473009471, -15}, 
			      {.6972380782,-15},
			      {5.651554158, -15}, 
			      {11.41930288, -15},
			      {13.68624880, -15}, 
			      {15, -15},
			      {-14.72118907, 55},
			      {-12.78820084, 55}, 
			      {-9.429541428, 55}, 
			      {-3.445577891, 55},
			      {.8677792011, 55}, 
			      {6.410963111, 55},
			      {9.702169436, 55},
			      {12.23452901, 55},
			      {15, 55}};

  public UrsemMultimodal6()
    {
      super();

      double[] optimums;

      name = "Ursem Multimodal 6";
      objectivefunction = new NumericalFitness(){
	      public double Fitness_calcFitness_inner(double[] realpos)
	      {
		  return (25+(10*Math.sin((realpos[0]*Math.cos(realpos[0])+realpos[1])/(2*Math.PI))*Math.cos(((realpos[0])/30)*Math.PI)))/(4+Math.sqrt(Math.pow(realpos[0]-4.5,2)+Math.pow(realpos[1]+2,2)));

	      };
	  };

      dimensions = 2;
      ismaximization = true;
      optimumradius = 0.2;

      intervals = new Interval[2];
      intervals[0] = new Interval(-15,15);
      intervals[1] = new Interval(-15,55);

      // Set up known maximas
      knownmaxima = new NumericalOptimum[lmax.length];

      for (int i=0;i<lmax.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmax[i][0];
	optimums[1] = lmax[i][1];
	knownmaxima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), true, false, i);
      }

      // Set up known minimas
      knownminima = new NumericalOptimum[lmin.length];

      for (int i=0;i<lmin.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmin[i][0];
	optimums[1] = lmin[i][1];
	knownminima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), false, false, i);
      }
    }
}
